package ubadb.bench.util;

import java.util.ArrayList;
import java.util.List;

import ubadb.core.common.PageId;
import ubadb.core.common.TableId;
import ubadb.external.bufferManagement.etc.PageReferenceTrace;
import ubadb.external.bufferManagement.etc.PageReferenceType;

public class PageReferenceTraceGenerator
		extends
		ubadb.external.bufferManagement.traceGenerators.PageReferenceTraceGenerator {

	public List<PageId> generateLoopPages(String fileName, int loopLength,
			int loops) {
		List<PageId> ret = new ArrayList<PageId>();

		for (int i = 0; i < loops; i++) {
			for (int j = 0; j < loopLength; j++)
				ret.add(new PageId(j, new TableId(fileName)));
		}

		return ret;
	}

	public PageReferenceTrace generateFileScan(String fileName, int start,
			int pageCount) {
		List<PageId> pages = generateSequentialPages(fileName, start, pageCount);

		return buildRequestAndRelease(null, pages);
	}

	public PageReferenceTrace generateIndexScanClustered(String fileName,
			int indexHeight, int referenceStart, int referenceCount) {
		PageReferenceTrace index = generateFileScan(fileName + "_index", 0,
				indexHeight);
		PageReferenceTrace fileScanFromIndex = generateFileScan(fileName,
				referenceStart, referenceStart + referenceCount);
		return index.concatenate(fileScanFromIndex);
	}

	public PageReferenceTrace generateIndexScanUnclustered(String fileName,
			int indexHeight, int referenceCount, int pageCount) {
		PageReferenceTrace index = generateFileScan(fileName + "_index", 0,
				indexHeight);
		PageReferenceTrace fileAccesses = buildRequestAndRelease(null,
				generateRandomPages(fileName, referenceCount, pageCount));
		return index.concatenate(fileAccesses);
	}

	public PageReferenceTrace generateBNLJ(String fileNameOuter,
			int pageCountOuter, String fileNameInner, int pageCountInner,
			int blockSize) {
		PageReferenceTrace ret = new PageReferenceTrace();
		int blocks = (int) Math.ceil((double) pageCountOuter
				/ (double) blockSize);
		int offset = 0;
		for (int i = 0; i < blocks; i++) {
			List<PageId> outerBlock = generateSequentialPages(fileNameOuter,
					offset, Math.min(offset + blockSize, pageCountOuter));
			ret.concatenate(build(null, outerBlock, PageReferenceType.REQUEST));
			ret.concatenate(generateFileScan(fileNameInner, 0, pageCountInner));
			ret.concatenate(build(null, outerBlock, PageReferenceType.RELEASE));

			offset += blockSize;
		}
		return ret;
	}

	public static void main(String[] args) {
		PageReferenceTraceGenerator gen = new PageReferenceTraceGenerator();
		// System.out.println(gen.generateFileScan("A",0,5));
		// System.out.println(gen.generateIndexScanClustered("A", 3, 3, 3));
		// System.out.println(gen.generateIndexScanUnclustered("A", 3, 3, 10));
		System.out.println(gen.generateBNLJ("A", 7, "B", 2, 3));
	}

}
